package com.lcj.service.impl;


import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;

/**
 * 消息提醒计数WebSocket
 *
 * // Cannot deploy POJO class [com.lcj.controller.WebSocketController$$SpringCGLIB$$0] as it is not annotated with @ServerEndpoint
 * @Scope("prototype")
 */
@ServerEndpoint("/ws/msg/{userId}")
@Component
@Scope("prototype")
@Slf4j
public class WebSocketService {
    /**
     * 用来存在线连接用户信息
     */
    private static final ConcurrentHashMap<String, Session> SESSION_POOL = new ConcurrentHashMap<>();

    /**
     * 与某个客户端的连接会话，需要通过它来给客户端发送数据
     */
    private Session currentSession;

    /**
     * 用户ID
     */
    private String userId;

    /**
     * 链接成功调用的方法
     */
    @OnOpen
    public void onOpen(Session currentSession, @PathParam(value = "userId") String userId) {
        this.currentSession = currentSession;
        this.userId = userId;
        SESSION_POOL.put(userId, currentSession);
        log.info("建立与UserID：{}的消息提醒计数连接", userId);
    }

    /**
     * 链接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        if(SESSION_POOL.containsKey(this.userId)){
            SESSION_POOL.remove(this.userId);
            log.info("关闭与UserID：{}的消息提醒计数连接", userId);
        }
    }

    /**
     * 收到客户端消息后调用的方法
     */
    @OnMessage
    public void onMessage(String message) {
        log.info("接收到UserID：{}的消息{}", userId, message);
    }

    /**
     * 发送错误时的处理
     */
    @OnError
    public void onError(Session currentSession, Throwable error) {
        log.error("发送到UserID：{}的消息传输失败", userId, error);
    }

    /**
     * 广播消息
     *
     * @param message   消息
     */
    public void sendAllMessage(String message) {
        for (Session session : SESSION_POOL.values()) {
            if (session.isOpen()) {
                session.getAsyncRemote().sendText(message);
            }
        }
    }

    /**
     * 单人单播消息
     *
     * @param userId    用户id
     * @param message   消息
     */
    public void sendOneMessage(String userId, String message) {
        Session session = SESSION_POOL.get(userId);
        if (session != null && session.isOpen()) {
            session.getAsyncRemote().sendText(message);
        }
    }

    /**
     * 多人单播消息
     *
     * @param userIds   多用户id
     * @param message   消息
     */
    public void sendMoreMessage(String[] userIds, String message) {
        for (String id : userIds) {
            Session session = SESSION_POOL.get(id);
            if (session != null && session.isOpen()) {
                session.getAsyncRemote().sendText(message);
            }
        }

    }
}
